﻿// -------------------------------------------------------------------------------------------------------------------------------
// <copyright file="TestSubtractCMDenseMatrix.cs" company="Exul">
//     Copyright (c) Exul. All rights reserved.
// </copyright>
// <author>
//     Exul
// </author>
// -------------------------------------------------------------------------------------------------------------------------------

namespace ExulLibrary.Mathematics.LinearAlgebra.Sequential.Tests.CMDenseMatrixTest.DoubleExtensions
{
    #region Usings

    using System;

    using ExulLibrary.Mathematics.LinearAlgebra.Sequential.DoubleExtensions;

    using NUnit.Framework;

    #endregion

    /// <summary>
    ///     Test suite for <see cref="CMDenseMatrixExtensions.Subtract(CMDenseMatrix{double},CMDenseMatrix{double})"/>.
    /// </summary>
    [TestFixture]
    [Category("ExulLibrary.Mathematics.LinearAlgebra.Sequential.DoubleExtensions.CMDenseMatrixExtensions")]
    public sealed class TestSubtractCMDenseMatrix
    {
        /// <summary>
        ///     Tests the method when minuend and subtrahend have the same size.
        /// </summary>
        [Test]
        public void WhenMinuendAndSubtrahendHaveTheSameSize()
        {
            // Arrange
            var minuendData = new[]
                              {
                                  new double[] { 10, 15 },
                                  new double[] { 20, 25 },
                                  new double[] { 30, 35 }
                              };
            var minuend = new CMDenseMatrix<double>(minuendData);
            var subtrahendData = new[]
                                 {
                                     new double[] { 1, 2 },
                                     new double[] { 3, 4 },
                                     new double[] { 5, 6 }
                                 };
            var subtrahend = new CMDenseMatrix<double>(subtrahendData);
            var expected = new[]
                           {
                               new double[] { 9, 13 },
                               new double[] { 17, 21 },
                               new double[] { 25, 29 }
                           };

            // Act
            minuend.Subtract(subtrahend);

            // Assert
            Assert.That(minuend.Values, Is.EquivalentTo(expected));
        }

        /// <summary>
        ///     Tests the method when subtrahend has less count of rows than minuend.
        /// </summary>
        [Test]
        public void WhenSubtrahendHasLessRowsCountThanMinuend()
        {
            // Arrange
            var minuendData = new[]
                              {
                                  new double[] { 10, 15 },
                                  new double[] { 20, 25 },
                                  new double[] { 30, 35 }
                              };
            var minuend = new CMDenseMatrix<double>(minuendData);
            var subtrahendData = new[]
                                 {
                                     new double[] { 1 },
                                     new double[] { 2 },
                                     new double[] { 3 }
                                 };
            var subtrahend = new CMDenseMatrix<double>(subtrahendData);
            var expected = new[]
                           {
                               new double[] { 9, 15 },
                               new double[] { 18, 25 },
                               new double[] { 27, 35 }
                           };

            // Act
            minuend.Subtract(subtrahend);

            // Assert
            Assert.That(minuend.Values, Is.EquivalentTo(expected));
        }

        /// <summary>
        ///     Tests the method when subtrahend have greater count of rows than minuend.
        /// </summary>
        [Test]
        public void WhenSubtrahendHasGreaterRowsCountThanMinuend()
        {
            // Arrange
            var minuendData = new[]
                              {
                                  new double[] { 10, 15 },
                                  new double[] { 20, 25 },
                                  new double[] { 30, 35 }
                              };
            var minuend = new CMDenseMatrix<double>(minuendData);
            var subtrahendData = new[]
                                 {
                                     new double[] { 1, 2, 3 },
                                     new double[] { 4, 5, 6 },
                                     new double[] { 7, 8, 9 }
                                 };
            var subtrahend = new CMDenseMatrix<double>(subtrahendData);
            var expected = new[]
                           {
                               new double[] { 9, 13 },
                               new double[] { 16, 20 },
                               new double[] { 23, 27 }
                           };

            // Act
            minuend.Subtract(subtrahend);

            // Assert
            Assert.That(minuend.Values, Is.EquivalentTo(expected));
        }

        /// <summary>
        ///     Tests the method when subtrahend has less count of columns than minuend.
        /// </summary>
        [Test]
        public void WhenSubtrahendHasLessColumnsCountThanMinuend()
        {
            // Arrange
            var minuendData = new[]
                              {
                                  new double[] { 10, 15 },
                                  new double[] { 20, 25 },
                                  new double[] { 30, 35 }
                              };
            var minuend = new CMDenseMatrix<double>(minuendData);
            var subtrahendData = new[]
                                 {
                                     new double[] { 1, 2 },
                                     new double[] { 3, 4 }
                                 };
            var subtrahend = new CMDenseMatrix<double>(subtrahendData);
            var expected = new[]
                           {
                               new double[] { 9, 13 },
                               new double[] { 17, 21 },
                               new double[] { 30, 35 }
                           };

            // Act
            minuend.Subtract(subtrahend);

            // Assert
            Assert.That(minuend.Values, Is.EquivalentTo(expected));
        }

        /// <summary>
        ///     Tests the method when subtrahend has greater count of columns than minuend.
        /// </summary>
        [Test]
        public void WhenSubtrahendHasGreaterColumnsCountThanMinuend()
        {
            // Arrange
            var minuendData = new[]
                              {
                                  new double[] { 10, 15 },
                                  new double[] { 20, 25 },
                                  new double[] { 30, 35 }
                              };
            var minuend = new CMDenseMatrix<double>(minuendData);
            var subtrahendData = new[]
                                 {
                                     new double[] { 1, 2 },
                                     new double[] { 3, 4 },
                                     new double[] { 5, 6 },
                                     new double[] { 7, 8 }
                                 };
            var subtrahend = new CMDenseMatrix<double>(subtrahendData);
            var expected = new[]
                           {
                               new double[] { 9, 13 },
                               new double[] { 17, 21 },
                               new double[] { 25, 29 }
                           };

            // Act
            minuend.Subtract(subtrahend);

            // Assert
            Assert.That(minuend.Values, Is.EquivalentTo(expected));
        }

#if SAFE

        /// <summary>
        ///     Tests the method when minuend is <see langword="null"/>.
        /// </summary>
        [Test]
        public void WhenMinuendIsNull()
        {
            // Arrange
            var subtrahendData = new[]
                                 {
                                     new double[2],
                                     new double[2],
                                     new double[2]
                                 };
            var subtrahend = new CMDenseMatrix<double>(subtrahendData);

            // Act and Assert
            Assert.That(
                () => CMDenseMatrixExtensions.Subtract(null, subtrahend),
                Throws.TypeOf<ArgumentNullException>().With.Property("ParamName").EqualTo("minuend"));
        }

        /// <summary>
        ///     Tests the method when subtrahend is <see langword="null"/>.
        /// </summary>
        [Test]
        public void WhenSubtrahendIsNull()
        {
            // Arrange
            var minuendData = new[]
                              {
                                  new double[2],
                                  new double[2],
                                  new double[2]
                              };
            var minuend = new CMDenseMatrix<double>(minuendData);

            // Act and Assert
            Assert.That(
                () => minuend.Subtract(null),
                Throws.TypeOf<ArgumentNullException>().With.Property("ParamName").EqualTo("subtrahend"));
        }

#endif
    }
}